package com.geniusk.app.controller;

import cn.hutool.json.JSONUtil;
import com.geniusk.app.utils.FollowUserUtil;
import com.geniusk.common.core.JSONResult;
import com.geniusk.common.utils.RedisUtil;
import com.geniusk.security.utils.SecurityUtil;
import com.geniusk.system.model.bo.followUser.FollowUserByUserIdBO;
import com.geniusk.system.model.bo.user.SelectUserByIdBO;
import com.geniusk.system.model.bo.user.SelectUserByMobileBO;
import com.geniusk.system.model.bo.user.SelectUserByUsernameBO;
import com.geniusk.system.model.pojo.User;
import com.geniusk.system.model.ro.FansUserRO;
import com.geniusk.system.model.ro.FollowUserRO;
import com.geniusk.system.model.vo.PublicUserVO;
import com.geniusk.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;

import static com.geniusk.common.constant.RedisConstants.FANS_USER_KEY;
import static com.geniusk.common.constant.RedisConstants.FOLLOW_USER_KEY;

/**
 * APP用户接口
 */
@RestController
@RequestMapping("/app/user")
public class AppUserController {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private FollowUserUtil followUserUtil;

    /**
     * ID查询用户
     * @param selectUserByIdBO 用户ID
     * @return 用户信息
     */
    @PostMapping("/selectUserById")
    public JSONResult selectUserById(@Valid @RequestBody SelectUserByIdBO selectUserByIdBO) {
        User user = userService.selectUserById(selectUserByIdBO.getUserId());
        PublicUserVO publicUserVO = JSONUtil.parse(user).toBean(PublicUserVO.class);
        followUserUtil.setFollow(publicUserVO);
        Map<String,Object> result = new HashMap<>();
        result.put("user",publicUserVO);
        return JSONResult.ok(result);
    }

    /**
     * 手机号查询用户
     * @param selectUserByMobileBO 用户手机号
     * @return 用户信息
     */
    @PostMapping("/selectUserByMobile")
    public JSONResult selectUserByMobile(@Valid @RequestBody SelectUserByMobileBO selectUserByMobileBO) {
        User user = userService.selectUserByMobile(selectUserByMobileBO.getPhoneNumber());
        Map<String,Object> result = new HashMap<>();
        if(user != null){
            PublicUserVO publicUserVO = JSONUtil.parse(user).toBean(PublicUserVO.class);
            followUserUtil.setFollow(publicUserVO);
            result.put("user",publicUserVO);
            result.put("exist",true);
        }else{
            result.put("exist",false);
        }
        return JSONResult.ok(result);
    }

    /**
     * 用户账号查询用户
     * @param selectUserByUsernameBO 用户账号
     * @return 用户信息
     */
    @PostMapping("/selectUserByUsername")
    public JSONResult selectUserByUsername(@Valid @RequestBody SelectUserByUsernameBO selectUserByUsernameBO) {
        User user = userService.selectUserByUserName(selectUserByUsernameBO.getUsername());
        Map<String,Object> result = new HashMap<>();
        if(user != null){
            PublicUserVO publicUserVO = JSONUtil.parse(user).toBean(PublicUserVO.class);
            followUserUtil.setFollow(publicUserVO);
            result.put("user",publicUserVO);
            result.put("exist",true);
        }else{
            result.put("exist",false);
        }
        return JSONResult.ok(result);
    }

    /**
     * 关注取关用户
     */
    @PostMapping("/followUserByUserId")
    public JSONResult followUserByUserId(@Valid @RequestBody FollowUserByUserIdBO followUserByUserIdBO) {
        Long userId = followUserByUserIdBO.getUserId();
        boolean follow = followUserByUserIdBO.isFollow();
        User user = userService.selectUserById(userId);
        if(user == null){
            return JSONResult.errorMsg("关注用户不存在");
        }
        String followUserKey = getFollowUserKey();
        setFollowerUser(followUserKey, follow, userId);
        Long currentUserId = SecurityUtil.getUserId();
        String fansUserKey = getFansUserKey(userId);
        setFansUser(fansUserKey,follow,currentUserId);
        return JSONResult.ok();
    }

    /**
     * 查询关注用户数量
     */
    @GetMapping("/selectFollowUserCount")
    public JSONResult selectFollowUserCount() {
        String followUserKey = getFollowUserKey();
        FollowUserRO followUserRO = redisUtil.getCacheObject(followUserKey);
        int count = 0;
        if(followUserRO != null){
            Map<Long, Date> userIdMap = followUserRO.getUserIdMap();
            count = userIdMap.size();
        }
        Map<String,Object> result = new HashMap<>();
        result.put("count",count);
        return JSONResult.ok(result);
    }

    /**
     * 分页查询查询关注用户
     */
    @PostMapping("/selectFollowUserByPage")
    public JSONResult selectFollowUserByPage() {
        String followUserKey = getFollowUserKey();
        FollowUserRO followUserRO = redisUtil.getCacheObject(followUserKey);
        List<PublicUserVO> publicUserVOList = new ArrayList<>();
        if(followUserRO != null){
            Map<Long, Date> userIdMap = followUserRO.getUserIdMap();
            for (Long userId:userIdMap.keySet()){
                User user = userService.selectUserById(userId);
                PublicUserVO publicUserVO = JSONUtil.parse(user).toBean(PublicUserVO.class);
                publicUserVO.setFollow(true);
                publicUserVO.setFollowTime(userIdMap.get(userId));
                publicUserVOList.add(publicUserVO);
            }
        }
        Map<String,Object> result = new HashMap<>();
        result.put("list",publicUserVOList);
        return JSONResult.ok(result);
    }

    /**
     * 查询用户粉丝数量
     */
    @GetMapping("/selectFansCount")
    public JSONResult selectFansCount() {
        String fansUserKey = getFansUserKey(SecurityUtil.getUserId());
        FansUserRO fansUserRO = redisUtil.getCacheObject(fansUserKey);
        int count = 0;
        if(fansUserRO != null){
            Map<Long, Date> userIdMap = fansUserRO.getUserIdMap();
            count = userIdMap.size();
        }
        Map<String,Object> result = new HashMap<>();
        result.put("count",count);
        return JSONResult.ok(result);
    }

    /**
     * 分页查询查询用户粉丝
     */
    @PostMapping("/selectFansByPage")
    public JSONResult selectFansByPage() {
        String fansUserKey = getFansUserKey(SecurityUtil.getUserId());
        FansUserRO fansUserRO = redisUtil.getCacheObject(fansUserKey);
        List<PublicUserVO> userInfoVOList = new ArrayList<>();
        if(fansUserRO != null){
            Map<Long, Date> userIdMap = fansUserRO.getUserIdMap();
            for (Long userId:userIdMap.keySet()){
                User user = userService.selectUserById(userId);
                PublicUserVO publicUserVO = JSONUtil.parse(user).toBean(PublicUserVO.class);
                publicUserVO.setFans(true);
                publicUserVO.setFansTime(userIdMap.get(userId));
                userInfoVOList.add(publicUserVO);
            }
        }
        Map<String,Object> result = new HashMap<>();
        result.put("list",userInfoVOList);
        return JSONResult.ok(result);
    }

    private void setFollowerUser(String followUserKey, boolean follow, Long userId){
        Boolean hasFollowUserKey = redisUtil.hasKey(followUserKey);
        FollowUserRO followUserRO;
        if(hasFollowUserKey){
            followUserRO = redisUtil.getCacheObject(followUserKey);
        }else{
            followUserRO = new FollowUserRO();
            Map<Long, Date> userIdMap = new HashMap<>();
            followUserRO.setUserIdMap(userIdMap);
        }
        Map<Long, Date> userIdMap = followUserRO.getUserIdMap();
        if(follow){
            if(!userIdMap.containsKey(userId)){
                userIdMap.put(userId,new Date());
                redisUtil.setCacheObject(followUserKey,followUserRO);
            }
        }else{
            userIdMap.remove(userId);
            if(userIdMap.isEmpty()){
                redisUtil.deleteObject(followUserKey);
            }else{
                redisUtil.setCacheObject(followUserKey,followUserRO);
            }
        }
    }

    private void setFansUser(String fansUserKey, boolean follow, Long userId){
        Boolean hasFansUserKey = redisUtil.hasKey(fansUserKey);
        FansUserRO fansUserRO;
        if(hasFansUserKey){
            fansUserRO = redisUtil.getCacheObject(fansUserKey);
        }else{
            fansUserRO = new FansUserRO();
            Map<Long, Date> userIdMap = new HashMap<>();
            fansUserRO.setUserIdMap(userIdMap);
        }
        Map<Long, Date> userIdMap = fansUserRO.getUserIdMap();
        if(follow){
            if(!userIdMap.containsKey(userId)){
                userIdMap.put(userId,new Date());
                redisUtil.setCacheObject(fansUserKey,fansUserRO);
            }
        }else{
            userIdMap.remove(userId);
            if(userIdMap.isEmpty()){
                redisUtil.deleteObject(fansUserKey);
            }else{
                redisUtil.setCacheObject(fansUserKey,fansUserRO);
            }
        }
    }

    /**
     * 获取用户关注缓存Key
     * @return 关注粉丝缓存Key
     */
    private String getFollowUserKey(){
        return FOLLOW_USER_KEY + SecurityUtil.getUserId();
    }

    /**
     * 获取用户粉丝缓存Key
     * @return 用户粉丝缓存Key
     */
    private String getFansUserKey(Long userId){
        return FANS_USER_KEY + userId;
    }

}
